﻿using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using QASPRibbon.Extensions;
using Schema = QASPRibbon.RibbonSchema;

namespace QASPRibbon.Controls
{
    /// <summary>
    /// Represents a Group control in the SharePoint Server Ribbon. 
    /// </summary>
    public class RibbonGroup : RibbonElement
    {
        #region Properties

        
        /// <summary>
        /// 
        /// </summary>
        public bool IsPopupable
        {
            get { return _isPopupable; }
            set { _isPopupable = value; }
        }

        /// <summary>
        /// A collection of child controls.
        /// </summary>
        public IEnumerable<RibbonGroupSection> Sections { get; set; }

        #endregion

        #region JavaScript

        /// <summary>
        /// Javascript code that executes when a Group is activated.
        /// </summary>
        public string OnClientActivate
        {
            get { return _onClientActivate; }
            set { _onClientActivate = value; }
        }

        #endregion

        #region Internal

        internal string TemplateId;

        internal override string XmlTag
        {
            get { return Schema.Group; }
        }

        internal override XElement AsXElement()
        {
            return AsXElement(string.Empty, 1);
        }

        private string _templateXml;
        internal string TemplateXml
        {
            get
            {
                if(string.IsNullOrEmpty(_templateXml))
                {
                    BuildTemplate();
                }
                return _templateXml;
            }
        }

        /// <summary>
        /// Gets or sets the Image displayed in the control.
        /// </summary>
        public RibbonImageDefinition PopupImage { get; set; }

        internal void BuildTemplate()
        {
            var gt = new RibbonGroupTemplateDef(this);
            _templateXml = gt.XML;
        }

        internal IEnumerable<RibbonControl> Controls
        {
            get
            {
                return Sections
                    .Where(s => s.Type != RibbonSectionType.Divider)
                    .SelectMany(s => s.Controls)
                    .ToList();
            }
        } 

        internal XElement AsXElement(string tabId, int groupIndex)
        {
            
            NameSpace = "Ribbon." + tabId;
            TemplateId = FullId + "Template";
            BuildTemplate();
            var groupId = NameSpace + "." + Id;

            var scalingElement = new XElement(Schema.Scaling,
                                              new XAttribute(Schema.Id, tabId + ".Scaling"),
                                              new XElement(Schema.MaxSize,
                                                           new XAttribute(Schema.Id, groupId + ".MaxSize"),
                                                           new XAttribute(Schema.GroupId, groupId),
                                                           new XAttribute(Schema.Size, groupId + Schema.Layout),
                                                           new XAttribute(Schema.Sequence, 10)));
            if (IsPopupable)
            {
                scalingElement.Add(new XElement(Schema.Scale,
                                                new XAttribute(Schema.Id, FullId + ".Popup"),
                                                new XAttribute(Schema.GroupId, FullId),
                                                new XAttribute(Schema.Size, Schema.Popup),
                                                new XAttribute(Schema.Sequence, 20)));
            }
            var groupElement = new XElement(XmlTag,
                                            new XAttribute(Schema.Id, FullId),
                                            new XAttribute(Schema.Title, Title),
                                            new XAttribute(Schema.Description, Description),
                                            new XAttribute(Schema.Sequence, groupIndex),
                                            new XAttribute(Schema.Template, TemplateId),
                                            new XElement(Schema.Controls, new XAttribute(Schema.Id, groupId + ".Controls")));



            if (PopupImage != null)
            {
                if (PopupImage.Url16 != null)
                    groupElement.Add(new XAttribute(Schema.Image16by16Popup, PopupImage.Url16));
                if (PopupImage.Url32 != null)
                    groupElement.Add(new XAttribute(Schema.Image32by32Popup, PopupImage.Url32));

                if (PopupImage.X.HasValue)
                {
                    if (PopupImage.Url16 != null)
                        groupElement.Add(new XAttribute(Schema.Image16by16PopupLeft, PopupImage.Position16X));
                    if (PopupImage.Url32 != null)
                        groupElement.Add(new XAttribute(Schema.Image32by32PopupLeft, PopupImage.Position32X));
                }

                if (PopupImage.Y.HasValue)
                {
                    if (PopupImage.Url16 != null)
                        groupElement.Add(new XAttribute(Schema.Image16by16PopupTop, PopupImage.Position16Y));
                    if (PopupImage.Url32 != null)
                        groupElement.Add(new XAttribute(Schema.Image32by32PopupTop, PopupImage.Position32Y));
                }
            }

            var controlIndex = 0;
            foreach (var control in Controls)
            {
                var strip = control as RibbonStrip;
                if(strip != null)
                {
                    foreach (var ctrl in strip.Controls)
                    {
                        controlIndex++;
                        ctrl.NameSpace = FullId + ".Controls";
                        ctrl.Sequence = controlIndex;
                        var controlElement = ctrl.AsXElement();
                        if (controlElement != null)
                            groupElement.Element(Schema.Controls).Add(controlElement);
                    }
                }
                else
                {
                    controlIndex++;
                    control.NameSpace = FullId + ".Controls";
                    control.Sequence = controlIndex;
                    var controlElement = control.AsXElement();
                    if (controlElement != null)
                        groupElement.Element(Schema.Controls).Add(controlElement);
                }
            }

            return new XElement("root", scalingElement, groupElement);
        }

        internal IEnumerable<RibbonControl> AllControls
        {
            get
            {
                var res = new List<RibbonControl>();
                var controlIndex = 0;
                foreach (var section in Sections.Where(c => c.Visible))
                {
                    controlIndex++;
                    section.NameSpace = FullId + ".Controls";
                    section.Sequence = controlIndex;
                    res.AddRange(section.AllControls);
                }
                return res;
            }
        }

        #endregion

        #region Constructors

        /// <summary>
        /// Creates and initializes a new instance of the RibbonGroup.
        /// </summary>
        public RibbonGroup() { }

        /// <summary>
        /// Creates and initializes a new instance of the RibbonGroup.
        /// </summary>
        /// <param name="id">Identifier</param>
        public RibbonGroup(string id) : base(id) { }

        /// <summary>
        /// Creates and initializes a new instance of the RibbonGroup.
        /// </summary>
        /// <param name="id">Identifier</param>
        /// <param name="title">Title</param>
        public RibbonGroup(string id, string title) : base(id, title) { }

        #endregion

        #region Private

        private string _onClientActivate = string.Empty;
        private bool _isPopupable = true;

        #endregion
    }
}
